package com.weilele.leisure.time.ui.module.main

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.weilele.base.library.BaseBindingFragment
import com.weilele.base.library.BaseFragment
import com.weilele.base.library.FragmentContainerActivity
import com.weilele.leisure.time.CommonHttp
import com.weilele.leisure.time.bean.PageByIdBean
import com.weilele.leisure.time.databinding.FragmentMainBinding
import com.weilele.leisure.time.ui.holder.*
import com.weilele.mvvm.adapter.*
import com.weilele.mvvm.base.helper.createViewModel
import com.weilele.mvvm.base.helper.refreshPageHelper
import com.weilele.mvvm.base.livedata.LiveDataWrap
import com.weilele.mvvm.base.livedata.StatusData
import com.weilele.mvvm.base.livedata.data
import com.weilele.mvvm.base.livedata.wrapObserver
import com.weilele.mvvm.utils.formJsonString
import com.weilele.mvvm.utils.safeGet
import com.weilele.mvvm.utils.toJsonString

class MainFragment : BaseBindingFragment<FragmentMainBinding>() {
    companion object {
        private const val KEY_PAGE_DATA = "KEY_PAGE_DATA"
        fun open(appCompatActivity: AppCompatActivity, pageData: PageByIdBean?) {
            FragmentContainerActivity.start<MainFragment>(
                appCompatActivity,
                bundle = Bundle().apply {
                    putString(KEY_PAGE_DATA, pageData?.toJsonString())
                })
            appCompatActivity.finish()
        }

        fun newInstance(
            pageData: PageByIdBean?
        ): MainFragment {
            return MainFragment().apply {
                arguments = Bundle().apply {
                    putString(KEY_PAGE_DATA, pageData?.toJsonString())
                }
            }
        }
    }

    private val pageData by lazy {
        arguments?.getString(KEY_PAGE_DATA)?.formJsonString<PageByIdBean>()
    }

    private val mainViewModel by lazy { createViewModel<MainViewModel>() }

    private val videoAdapter by lazy {
        mvvmRcvAdapter({ old, new -> old == new }, ::arePageContentSame).apply {
            register(SimpleTextTitleHolder::class.java)
            register(HomeBannerHolder::class.java)
            register(VideoItemHolder::class.java)
            register(PlaceholderHolder::class.java)
            register(LoadingHolder::class.java)
        } as MvvmRcvAdapter<Any>
    }
    private val loadMoreAdapter by lazy { LoadingHolder.toAdapter() }

    private val rcvAdapter by lazy { mvvmConcatAdapter(videoAdapter, loadMoreAdapter) }

    private val pageLiveData
        get() = mainViewModel.getPageData(pageData)
    private val initLoadMore by lazy {
        pageLiveData.data?.setOnListScrollEndListener(videoAdapter) {
            mainViewModel.loadMore(pageData)
        }
    }

    override fun initUi(savedInstanceState: Bundle?) {
        super.initUi(savedInstanceState)
        setPageLayoutManage()
        //数据为加载前，显示占位加载的视图
        videoAdapter.refreshList(mainViewModel.pagesToAdapterDatas(pageData))
    }

    override fun initData() {
        super.initData()
        mainViewModel.getVideos(pageData)
    }

    override fun getObserverLiveData(): List<LiveDataWrap>? {
        return listOf(
            pageLiveData wrapObserver {
                when (it?.status) {
                    StatusData.Running -> {

                    }
                    StatusData.Error -> {

                    }
                    StatusData.Success -> {
                        initLoadMore
                        it.data?.let { page ->
                            videoAdapter.refreshPageHelper(page)
                            val loadBean = if (page.hasNextPage) {
                                LoadingHolder.Bean("正在努力加载", true)
                            } else {
                                LoadingHolder.Bean("所有数据加载完毕", false)
                            }
                            loadMoreAdapter.refreshList(mutableListOf(loadBean))
                        }

                    }
                }
            }
        )
    }

    private fun setPageLayoutManage() {
        val spanCount = 3
        val manager = GridLayoutManager(this.context, spanCount)
        manager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
            override fun getSpanSize(position: Int): Int {
                val datas = mutableListOf<Any>()
                rcvAdapter.adapters.forEach {
                    it.safeGet<MvvmRcvAdapter<Any>>()?.let {
                        datas.addAll(it.currentList)
                    }
                }
                return when (datas[position]) {
                    is VideoItemHolder.Bean -> {
                        1
                    }
                    else -> {
                        spanCount
                    }
                }
            }
        }
        mBinding.rcv.layoutManager = manager
        mBinding.rcv.adapter = rcvAdapter
        mBinding.rcv.setHasFixedSize(true)
    }

    private fun arePageContentSame(old: Any?, new: Any?): Boolean {
        return when {
            old is SimpleTextTitleHolder.Bean
                    && new is SimpleTextTitleHolder.Bean -> {
                old.title == new.title
                        && old.hint == new.hint
                        && old.hintCoin == new.hintCoin
            }
            old is HomeBannerHolder.Bean
                    && new is HomeBannerHolder.Bean -> {
                old.data.id == new.data.id
            }
            old is VideoItemHolder.Bean
                    && new is VideoItemHolder.Bean -> {
                old.data.id == new.data.id
            }
            old is PlaceholderHolder.Bean
                    && new is PlaceholderHolder.Bean -> {
                true
            }
            old is LoadingHolder.Bean
                    && new is LoadingHolder.Bean -> {
                //必须返回false，否在无法触发加载回调
                false
            }
            else -> false
        }
    }
}